import {
	createRef,
	forwardRef,
	ForwardRefRenderFunction,
	useCallback,
	useContext,
	useImperativeHandle,
	useMemo,
	useRef,
	useState,
} from "react";
import { ConfigurePageContext } from "../../ConfigurePage";
import { ConfigurePageContentItem, SwiperItem } from "../../ConfigurePageType";
import { DeleteOutlined, PlusOutlined, LeftOutlined, RightOutlined, EyeOutlined, EditOutlined } from "@ant-design/icons";
import { Button, Form, FormInstance, message, Popconfirm, Switch, Tooltip } from "antd";
import { useMount, useUploadImage } from "src/hooks";
import { cloneDeep } from "lodash";
import { StyledImgWrapper, StyledSwiperEditoWrapper, StyledUploadBox } from "../../ConfigurePage.styled";
import SwiperForm, { SwiperFormRef } from "./components/SwiperForm";
import ExtraTable, { ExtraTableRef } from "@/components/dataEntry/ExtraTable";
import ImgPreview from "@/components/dataPresentation/ImgPreview";

export interface SwiperEditorRef {
	initValues: (currentContent?: ConfigurePageContentItem[]) => void;
}
const SwiperEditor: ForwardRefRenderFunction<SwiperEditorRef> = (props, ref) => {
	useImperativeHandle(ref, () => ({
		initValues,
	}));
	const { content, setContent, selectedIndex } = useContext(ConfigurePageContext);
	const initValues = (currentContent?: ConfigurePageContentItem[]) => {
		swiperFormRefs.forEach((item) => item.current?.initValues(currentContent));
		if (currentContent !== undefined) {
			if (selectedIndex !== null) {
				const { extra, status = true } = currentContent[selectedIndex];
				extraTableRef.current?.initValues(extra);
				moduleFormRef.current?.setFieldValue("status", status);
			}
		}
	};
	if (selectedIndex === null) return <></>;
	const list = useMemo(() => content[selectedIndex].list as SwiperItem[], [content, selectedIndex]);
	const operateImgIndex = useRef<number>();
	const isReplaceImg = useRef(false);
	const uploadCallback = useCallback(
		(src: string) => {
			if (operateImgIndex.current === undefined) return;
			const copiedContent = cloneDeep(content);
			if (isReplaceImg.current) {
				(copiedContent[selectedIndex].list[operateImgIndex.current] as SwiperItem) = {
					...copiedContent[selectedIndex].list[operateImgIndex.current],
					src,
				};
				message.success("已修改");
			} else {
				copiedContent[selectedIndex].list.splice(operateImgIndex.current, 0, { src, link: "", status: true });
				message.success("已添加");
			}
			setContent(copiedContent);
		},
		[content, selectedIndex]
	);
	const { upload } = useUploadImage(uploadCallback);
	const clickUpload = useCallback(
		(index?: number) => {
			operateImgIndex.current = index !== undefined ? index : list.length;
			upload();
		},
		[list]
	);
	const [currentImgIndex, setCurrentImgIndex] = useState<number | undefined>();
	const changeModuleItem = (params: { currentContent?: ConfigurePageContentItem[]; options: Record<string, unknown> }) => {
		const { currentContent = content, options } = params;
		const copiedContent = cloneDeep(currentContent);
		copiedContent[selectedIndex] = { ...copiedContent[selectedIndex], ...options };
		setContent(copiedContent);
		return copiedContent;
	};
	const initStatus = useCallback(() => {
		const { status = true } = content[selectedIndex];
		changeModuleItem({ options: { status } });
		moduleFormRef.current?.setFieldValue("status", status);
	}, [content, selectedIndex]);
	useMount(() => {
		initStatus();
	});
	const moveImg = useCallback(
		(target: number, current: number) => {
			const list = cloneDeep(content[selectedIndex].list);
			if (target === -1) {
				list.splice(current - 1, 0, list.splice(current, 1)[0]);
				currentImgIndex !== undefined && setCurrentImgIndex(currentImgIndex - 1);
			}
			if (target === 1) {
				list.splice(current + 1, 0, list.splice(current, 1)[0]);
				currentImgIndex !== undefined && setCurrentImgIndex(currentImgIndex + 1);
			}
			const copiedContent = changeModuleItem({ currentContent: content, options: { list } });
			initValues(copiedContent);
			message.success("已移动");
		},
		[selectedIndex, content, currentImgIndex]
	);
	const [previewSrc, setPreviewSrc] = useState("");
	const swiperFormRefs = useMemo(() => list.map(() => createRef<SwiperFormRef>()), [list]);
	const extraTableRef = useRef<ExtraTableRef | null>(null);
	const moduleFormRef = useRef<FormInstance | null>(null);
	return (
		<StyledSwiperEditoWrapper className="overflow-y-scroll">
			<div className="flex flex-wrap">
				{list.map((item, index) => (
					<StyledImgWrapper
						key={index}
						onClick={() => setCurrentImgIndex(currentImgIndex === index ? undefined : index)}
						className="relative mr-3 rounded-sm overflow-hidden mb-2"
						style={{ ...(currentImgIndex === index ? { border: "2px dashed red" } : { border: "2px dashed transparent" }) }}
					>
						<img
							width={200}
							height={130}
							className="object-cover object-center border-gray-400 border border-solid rounded-sm"
							src={`${process.env.REACT_APP_BASEURL}${item.src}`}
						/>
						<div className="mask cursor-pointer w-full h-full absolute top-0 left-0 z-10 justify-around items-center">
							<Button
								className={`${index === 0 ? "invisible" : "visible"}`}
								icon={<LeftOutlined />}
								shape="circle"
								size="small"
								onClick={(e) => {
									moveImg(-1, index);
									e.stopPropagation();
								}}
							/>
							<div className="flex">
								<Tooltip title="删除图片" placement="bottom">
									<Popconfirm
										title="确认删除吗？"
										onConfirm={(e) => {
											e?.stopPropagation();
											const copiedContent = cloneDeep(content);
											copiedContent[selectedIndex].list.splice(index, 1);
											setContent(copiedContent);
											if (currentImgIndex === index) {
												setCurrentImgIndex(undefined);
											}
										}}
									>
										<Button
											onClick={(e) => e.stopPropagation()}
											shape="circle"
											size="small"
											danger
											icon={<DeleteOutlined />}
										/>
									</Popconfirm>
								</Tooltip>
								<Tooltip title="预览">
									<Button
										onClick={(e) => {
											setPreviewSrc(item.src);
											e.stopPropagation();
										}}
										className="ml-2"
										type="primary"
										icon={<EyeOutlined />}
										size="small"
										shape="circle"
									/>
								</Tooltip>
								<Tooltip title="重新上传图片">
									<Button
										onClick={(e) => {
											isReplaceImg.current = true;
											clickUpload(index);
											e.stopPropagation();
										}}
										className="ml-2"
										type="primary"
										icon={<EditOutlined />}
										size="small"
										shape="circle"
									/>
								</Tooltip>
								<Tooltip title="在后面添加图片">
									<Button
										onClick={(e) => {
											isReplaceImg.current = false;
											clickUpload(index + 1);
											e.stopPropagation();
										}}
										className="ml-2"
										type="primary"
										icon={<PlusOutlined />}
										size="small"
										shape="circle"
									/>
								</Tooltip>
							</div>
							<Button
								className={`${index === list.length - 1 ? "invisible" : "visible"}`}
								icon={<RightOutlined />}
								shape="circle"
								size="small"
								onClick={(e) => {
									moveImg(1, index);
									e.stopPropagation();
								}}
							/>
						</div>
					</StyledImgWrapper>
				))}
				<Tooltip title="添加图片" placement="right">
					<StyledUploadBox
						onClick={() => clickUpload()}
						className="flex justify-center items-center border border-dashed border-slate-400 rounded cursor-pointer"
					>
						<PlusOutlined style={{ color: "rgb(148 163 184)", fontSize: "25px" }} />
					</StyledUploadBox>
				</Tooltip>
			</div>
			<Form
				className={list.length > 0 ? "" : "mt-3"}
				ref={moduleFormRef}
				labelAlign="left"
				labelCol={{ span: 4 }}
				wrapperCol={{ span: 18 }}
				initialValues={{ status: true }}
			>
				<Form.Item label="状态" valuePropName="checked" name="status">
					<Switch
						checkedChildren="启用"
						unCheckedChildren="禁用"
						onChange={(status) => changeModuleItem({ options: { status } })}
					/>
				</Form.Item>
				<Form.Item label="模块额外信息">
					<ExtraTable
						ref={extraTableRef}
						reflectExtra={(extra = []) => {
							const copiedContent = cloneDeep(content);
							copiedContent[selectedIndex].extra = extra.reduce((pre, item) => ({ ...pre, [item._key]: item._value }), {});
							setContent(copiedContent);
						}}
					/>
				</Form.Item>
			</Form>
			{list.map((item, index) => (
				<SwiperForm
					key={index}
					className={`${index === currentImgIndex ? "flex" : "hidden"}`}
					ref={swiperFormRefs[index]}
					currentImgIndex={index}
					selectedIndex={selectedIndex}
				/>
			))}
			<ImgPreview src={previewSrc} onHide={() => setPreviewSrc("")} />
		</StyledSwiperEditoWrapper>
	);
};

export default forwardRef(SwiperEditor);
